/*#include <stdio.h>
#include <stdlib.h>
#include "fs.h"
*/
#include "../include/fs.h"
#include "../include/video.h"
/*
void pr_mat(inode ** fs);
#define print printf
int main() {

	inode ** fs;
	int path [DEEP];
	int i;

	fs = malloc(MAX_INODE * sizeof(inode *));
	for(i = 0; i < MAX_INODE; i++){
		*(fs + i) = malloc(DEEP * sizeof(inode));
	}

	char input [MAX_LEN_NAME];
	char poesia [] = "Volverán las oscuras golondrinas\nen tu balcón sus nidos a colgar,\ny otra vez con el ala a sus cristales\njugando llamarán.";/nPero aquellas que el vuelo refrenaban\ntu hermosura y mi dicha a contemplar,\naquellas que aprendieron nuestros nombres...\n¡esas... no volverán!.\n\nVolverán las tupidas madreselvas\nde tu jardín las tapias a escalar,\ny otra vez a la tarde aún más hermosas\nsus flores se abrirán.\n\nPero aquellas, cuajadas de rocío\ncuyas gotas mirábamos temblar\ny caer como lágrimas del día...\n¡esas... no volverán!\n\nVolverán del amor en tus oídos\nlas palabras ardientes a sonar;\ntu corazón de su profundo sueño\ntal vez despertará.\n\nPero mudo y absorto y de rodillas\ncomo se adora a Dios ante su altar,\ncomo yo te he querido...; desengáñate,\n¡así... no te querrán!";
	init_fs(fs);
	initPath(path);

pr_mat(fs);

//	print_path(fs,path);

	//mkdir(fs,path,"home");
	mkdir(fs,path,"dev");
	cd(fs,path,"home");
	creat(fs,path,"a.txt","hola mundo!!!!");
	creat(fs,path,"b.txt","hola mundo!!!!");
	creat(fs,path,"becker.txt",poesia);

	cd(fs,path,"..");
	//	print_path(fs,path);

	while (1) {
		printf("\n");
		print_path(fs,path);
		printf("cd: ingrese un directorio\n");
		scanf("%s",input);
		if (cmp_str("q",input)!=0)
		cd(fs,path,input);
		ls(fs,path);

		printf("mkdir: cree un directorio");
		scanf("%s",input);
		if (cmp_str("q",input)!=0)
		mkdir(fs,path,input);
		ls(fs,path);
		pr_mat(fs);

		printf("rmdir: elimine un directorio");
		scanf("%s",input);
		if (cmp_str("q",input)!=0)
		rmdir(fs,path,input);
		ls(fs,path);

		printf("creat: crear un archivo");
		scanf("%s",input);
		if (cmp_str("q",input)!=0)
		creat(fs,path,input,poesia);
		ls(fs,path);

		printf("cat: elija un archivo");
		scanf("%s",input);
		if (cmp_str("q",input)!=0)
		cat(fs,path,input);
		ls(fs,path);

		printf("rm: eliminar un archivo");
		scanf("%s",input);
		if (cmp_str("q",input)!=0)
		rm(fs,path,input);
		ls(fs,path);
	}

printf ("exitos");
	return 0;
}
*/
/*
void pr_mat(inode ** fs){
	int i,j;

	for(i = 0; i < MAX_INODE; i++){
		for (j=0 ; j<DEEP;j++){
			print("%d\t",(*(fs+i)+j)->type);
	}
	print("\n");
	}
}
*/
int mkdir(inode **fs, int path[], char dir_name[]) {
	int col,k;

	if (cmp_str("..", dir_name) == 0) {
		print("\"..\" no es un directorio valido\n");
		return 0;
	}

	if (dirExists(fs, path, dir_name) == 1) {
		print("El directorio \"");
		print(dir_name);
		print("\" ya existe\n");
		return 0;
	}
	col = last_dir_col(path);
	/*si hay espacio para directorios*/
	for (k = 0; k < MAX_DIRS; k++){
		if ((*(fs + path[col] ) + col)->next_dirs[k] == EMPTY ){
			break;
		}
	}
	if (k == MAX_DIRS ){
		print("No hay mas espacio para crear mas directorios en este\n");
		return 0;
	}

	/*busco el primer slot libre*/
	for (k = 0; k < MAX_INODE; k++) {

		if ((*(fs + k) + (col + 1))->type == EMPTY) {
			create_dir(dir_name, fs, k , col + 1, path[col]);
			return 1;//se creo el directorio
		}
	}

	return 0;/*no hay mas lugar para crear directorios*/
}

void create_dir(char name[], inode **fs, int i, int j, int prev_d) {
	int k;

	(*(fs + i) + j)->source = prev_d;
	(*(fs + i) + j)->type = DIR;
	copy_name((*(fs + i) + j)->name, name);
	(*(fs + i) + j)->prev_dir = prev_d;
	/*seteo en el padre este directorio en su arreglo de directorios siguientes*/
	for (k = 0; k < MAX_DIRS; k++) {
		if ((*(fs + prev_d) + (j - 1))->next_dirs[k] == EMPTY) {
			(*(fs + prev_d) + (j - 1))->next_dirs[k] = i;
			break;
		}
	}
	/*seteo los nextDirs*/
	for (k = 0; k < MAX_DIRS; k++) {
		(*(fs + i) + j)->next_dirs[k] = EMPTY;
	}
	/*seteo los nextFiles*/
	for (k = 0; k < MAX_FILES; k++) {
		(*(fs + i) + j)->next_files[k] = EMPTY;
	}
}

void copy_name(char dest[], char orig[]) {
	int i;
	for (i = 0; i < MAX_LEN_NAME; i++) {
		if (orig[i] != '\0') {
			dest[i] = orig[i];
		} else {
			dest[i] = '\0';
			break;
		}
	}
}
/*tested*/
void init_fs(inode ** fs) {
	int i, j, k;
	for (i = 0; i < MAX_INODE; i++) {
		for (j = 0; j < DEEP; j++) {
			(*(fs + i) + j)->type = EMPTY;
		}
	}

	/*creo la raiz*/
	((*fs+0)+0)->type = DIR;
	copy_name((*fs)->name, "/root");
	((*fs+0)+0)->prev_dir = EMPTY;

	/*seteo los nextDirs*/
	for (k = 0; k < MAX_DIRS; k++) {
		((*fs+0)+0)->next_dirs[k] = EMPTY;
	}

	/*seteo los nextFiles*/
	for (k = 0; k < MAX_FILES; k++) {
		((*fs+0)+0)->next_files[k] = EMPTY;
	}

}
/*tested*/
void initPath(int * path) {
	int i;
	/*inicializo path*/
	for (i = 0; i < DEEP; i++) {
		path[i] = EMPTY;
	}

	/*seteo el path*/
	path[0] = 0;
}

void print_path(inode ** fs, int path[]) {
	int i;
	for (i = 0; i < DEEP; i++) {
		if (path[i] != EMPTY) {

			print((*(fs + path[i]) + i)->name);
			print("/");
		} else {
			//print("\n");
			break;
		}
	}
}

void cd(inode **fs, int path[], char dir_name[]) {
	int col;

	if (cmp_str(dir_name, "..") == 0) {
		col = last_dir_col(path);
		if (col > 0) {
			path[col] = EMPTY;
		}

	} else if (isDirValid(fs, path, dir_name) == 1) {
		/*actualiza el path posicionandose sobre el directorio pedido*/
	} else {
		print(dir_name);
		print(" no es un directorio valido\n");
	}
	//print_path(fs,path);
}

int isDirValid(inode **fs, int path[], char dir_name[]) {
	int i, col, i_hijo;
	col = last_dir_col(path);

	for (i = 0; i < MAX_DIRS /*|| fs[col][path[col]].next_dirs[i] != EMPTY*/; i++) {
		//if (fs[col][path[col]].next_dirs[i] != EMPTY){
		if ((*(fs +  path[col]) + col) ->next_dirs[i] != EMPTY) {
			i_hijo = (*(fs + path[col]) + col)->next_dirs[i];
			if (cmp_str((*(fs + i_hijo) + col + 1)->name, dir_name) == 0) {
				path[col + 1] = i_hijo;
				return 1;
			}
		}
	}
	return 0;
}

int cmp_str(char s1[], char s2[]) {
	int i;
	for (i = 0; s1[i] != '0' && s2[i] != '\0'; i++) {
		if (s1[i] != s2[i]) {
			return -1;
		}
	}
	return 0;
}

/*devuelve la columna del directorio actual*/
int last_dir_col(int path[]) {
	int i = 0;
	while (path[i] != EMPTY) {
		i++;
	}
	return i - 1;
}

void ls(inode **fs, int path[]) {
	int i;
	int col = last_dir_col(path);

	for (i=0; i<MAX_INODE ;i++){
		if ( (*(fs + i) + col +1)->source == path[col] ){
			if ((*(fs + i) + col +1)->type == DIR){
				print((*(fs + i) + col + 1)->name);
				print("/\n");
			}else if ((*(fs + i) + col +1)->type == FILE){
				print((*(fs + i) + col + 1)->name);
				print("\n");
			}
		}
	}
}

int dirExists(inode **fs, int path[], char dir_name[]) {
	int i, i_hijo;
	int col = last_dir_col(path);

	for (i = 0; i < MAX_DIRS && (*(fs + path[col]) + col)->next_dirs[i]
			!= EMPTY; i++) {
		i_hijo = (*(fs + path[col]) + col)->next_dirs[i];
		if (cmp_str((*(fs + i_hijo) + (col + 1))->name, dir_name) == 0)
			return 1;
	}
	return 0;
}

int rmdir(inode **fs, int path[], char dir_name[]) {
	int i, i_hijo,i_hijo_f,i1;
	char * file_name;
	int col = last_dir_col(path);

	for (i = 0; i < MAX_DIRS ; i++) {
		if ((*(fs + path[col]) + col)->next_dirs[i] != EMPTY){
			i_hijo = (*(fs + path[col]) + col)->next_dirs[i];
			/*vep si es el directorio q busco*/
			if (cmp_str((*(fs + i_hijo) + (col + 1))->name, dir_name) == 0) {
				/*chequeo q no tenga directorios adentro*/
				for ( i1 = 0; i1 < MAX_DIRS ; i1++) {
					if ((*(fs + i_hijo) + (col + 1))->next_dirs[i1] > EMPTY){
						print("El directorio no se puede eliminar porque contiene otros directorios\n");
						return 0;
					}
				}
				/*TODO: eliminar todos los archivos del directorio*/
				for ( i1 = 0; i1 < MAX_FILES ; i1++) {
					if ( (i_hijo_f = (*(fs + i_hijo) + (col + 1))->next_files[i1]) != EMPTY){
						( *(fs + i_hijo_f ) + col + 2)->type=EMPTY;
					}
				}

				(*(fs + path[col]) + col)->next_dirs[i] = EMPTY;
				(*(fs + i_hijo) + (col + 1))->type = EMPTY;
				return 1;
			}
		}
	}
	print("El directorio no existe\n");
	return 0;
}

void creat(inode **fs, int path[], char file_name[], char file[]) {
	int i, j, k, k1, col;
	/*busca el directorio(i,j) en el que estoy parado*/
	for (j = 0; j < DEEP; j++) {
		if (path[j] != EMPTY) {
			i = path[j];
		} else {
			j--;
			break;
		}
	}

	if (cmp_str("..", file_name) == 0) {
		print("\"..\" no es un nombre de archivo valido\n");
		return;
	}

	if (filExists(fs, path, file_name) == 1) {
		print("El archivo");
		print(file_name);
		print("ya existe\n");
		return;
	}

	col = last_dir_col(path);

	/*busco el primer slot libre*/
	for (k = 0; k < MAX_INODE; k++) {
		if ((*(fs + k) + (j + 1))->type == EMPTY) {
			(*(fs + k) + (j + 1))->type = FILE;
			(*(fs + k) + (j + 1))->source = i;

			/*agrego el archivo en los nextfiles del padre*/
			for (k1 = 0; k1 < MAX_FILES; k1++) {
				if ((*(fs + path[col]) + col)->next_files[k1] == EMPTY) {
					(*(fs + path[col]) + col)->next_files[k1] = k;
					k1 = 0;
					break;
				}
			}
			if (k1 != 0) {/*el padre no puede contener mas archivos*/
				(*(fs + k) + (j + 1))->type = EMPTY;
				break;
			}

			copy_name((*(fs + k) + (j + 1))->name, file_name);
			cp((*(fs + k) + (j + 1))->file_dir, file);
			break;
		}
	}
}

int filExists(inode **fs, int path[], char file_name[]) {
	int i, i_hijo;
	int col = last_dir_col(path);

	for (i = 0; i < MAX_FILES; i++) {
		if ((*(fs + path[col]) + col)->next_files[i] != EMPTY) {
			i_hijo = (*(fs + path[col]) + col)->next_files[i];
			if (cmp_str((*(fs + i_hijo) + col + 1)->name, file_name) == 0)
				return 1;
		}
	}
	return 0;
}

void cp(char dest[], char orig[]) {
	int i;
	for (i = 0; i < MAX_LEN_FILE; i++) {
		if (orig[i] != '\0') {
			dest[i] = orig[i];
		} else {
			dest[i] = '\0';
			break;
		}
	}
}

int cat(inode **fs, int path[], char file_name[]) {
	int i, j;
	if (filExists(fs, path, file_name) != 1) {
		print("El archivo ");
		print(file_name);
		print(" no existe\n");
		return 0;
	}
	j = last_dir_col(path);
	for (i = 0; i < MAX_INODE; i++) {
		if (cmp_str((*(fs + i) + (j + 1))->name, file_name) == 0) {
			print((*(fs + i) + (j + 1))->file_dir);
			return 1;
		}
	}
	return 0;
}

void rm(inode **fs, int path[], char file_name[]) {
	int i, i_hijo;
	int col = last_dir_col(path);

	for (i = 0; i < MAX_FILES && (*(fs + path[col]) + col)->next_files[i]
			!= EMPTY; i++) {
		i_hijo = (*(fs + path[col]) + col)->next_files[i];
		if (cmp_str((*(fs + i_hijo) + (col + 1))->name, file_name) == 0) {
			(*(fs + path[col]) + col)->next_files[i] = EMPTY;
			(*(fs + i_hijo) + (col + 1)) -> type = EMPTY;
			return;
		}
	}
	print("El archivo ");
	print(file_name);
	print(" no existe\n");
}

int rename(inode **fs, int path[], char* file_name, char * newfilename) {
	int i, i_hijo;
	int col = last_dir_col(path);

		if (!filExists(fs, path, file_name)) {
			print("No existe el archivo\n");
			return 0;
		}

		for (i = 0; i < MAX_FILES; i++) {
			if ((*(fs + path[col]) + col)->next_files[i] != EMPTY) {
				i_hijo = (*(fs + path[col]) + col)->next_files[i];
				if (cmp_str((*(fs + i_hijo) + col + 1)->name, file_name) == 0) {
					copy_name((*(fs + i_hijo) + col + 1)->name, newfilename);
					return 1;
				}
			}

		}

	return 0;
}
int renamedir(inode **fs, int path[], char* dir_name, char * newdir_name) {
	int i, i_hijo, files;
	int col = last_dir_col(path);

		if (!dirExists(fs, path, dir_name)) {
			print("No existe el directorio\n");
			return 0;
		}

		for (i = 0; i < MAX_DIRS; i++) {
			if ((*(fs + path[col]) + col)->next_dirs[i] != EMPTY) {
				i_hijo = (*(fs + path[col]) + col)->next_dirs[i];
				if (cmp_str((*(fs + i_hijo) + col + 1)->name, dir_name) == 0) {
					copy_name((*(fs + i_hijo) + col + 1)->name, newdir_name);
					return 1;
				}
			}

		}

	return 0;
}

void find(inode **fs, int path[], char* file_name,int recursive) {
	int i;
	int i_hijo = 0;
	int col = last_dir_col(path);

	if (filExists(fs, path, file_name)) {
		print_path(fs,path);
		print(file_name);
		print("\n");
	}
	if (recursive == 1) {
		for (i=0; i < MAX_DIRS ; i++){
			if ( ( i_hijo =(*(fs + path[col]) + col)->next_dirs[i] )!= EMPTY){
				cd(fs,path,(*(fs + i_hijo) + col+1)->name);
				//path[col+1] = i_hijo;
				find(fs,path,file_name,1);
				//path[col+1] = EMPTY;
				cd(fs,path,"..");
		 	}
		 }
	}


}


